package main

import (
	"fmt"
	"math"
	"os"
)

// 面积错误结构体
type areaError struct {
	err    string
	redius float64
}

// 实现error接口
func (e *areaError) Error() string {
	return fmt.Sprintf("radius %0.2f: %s", e.redius, e.err)

}

// 计算圆面积
func circleArea(redius float64) (float64, error) {
	if redius < 0 {
		// return 0, errors.New("Area calculation failed, radius is less than zero")
		// return 0, fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", redius)
		return 0, &areaError{"radius is negative", redius}
	}
	return math.Pi * redius * redius, nil
}

func test() {
	fmt.Println("错误处理")
	f, err := os.Open("./test.txt")
	// 打印全部错误信息
	// if err != nil {
	// 	fmt.Println(err)
	// 	return
	// }
	// 提取具体错误信息，通过断言获取底层接口提PathError参数
	if err, ok := err.(*os.PathError); ok {
		fmt.Println("File at path", err.Path, "failed to open")
		return
	}

	fmt.Println(f.Name(), "open sucessfully")
}

func test1() {
	fmt.Println("自定义错误")
	var redius float64
	redius = -20
	area, err := circleArea(redius)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(area)
	}
}

func test2() {
	fmt.Println("使用结构体类型和字段提供错误信息")
	redius := -20.0
	area, err := circleArea(redius)
	if err != nil {
		if err, ok := err.(*areaError); ok {
			fmt.Printf("Radius %0.2f is less than zero", err.redius)
			return
		}
		fmt.Println(err)
		return
	}
	fmt.Printf("Area of rectangle1 %0.2f", area)

}

func main() {
	// test()
	// test1()
	test2()
}
